#include "myString.h"
// #include <iostream>
#include <cstring>
#include <string>
const int defaultSize = 15;
const int BUFFER_SIZE = 128;
myString::myString()
{
    size = 0;
    capacity = defaultSize;
    this->string = new char[capacity];
    memset(this->string, 0, sizeof(string));
}

myString::myString(const char *str)
{
    int len = strlen(str);
    this->size = len;
    if (len <= defaultSize)
    {
        this->capacity = defaultSize;
    }
    else
    {
        this->capacity = len + 1;
    }
    this->string = new char[this->capacity];
    strncpy(this->string, str, len);
}

myString::myString(const myString &str)
{
    this->size = str.size;
    this->capacity = str.capacity;
    this->string = new char[str.capacity];
    memset(string, 0, capacity);
    strncpy(this->string, str.string, this->size);
}

myStringList myString::split(const myString &token)
{
    myStringList list;
    char *accord = strtok(this->string, token.string);
    while (accord != nullptr)
    {
        list += accord;
        accord = strtok(nullptr, token.string);
    }
    return list;
}

myString myString::operator+(const myString &str)
{

#if 1
    char temp[BUFFER_SIZE] = {0};
    strcpy(temp, this->string);
    strcat(temp, str.string);
    myString newStr(temp);
#else
    myString newStr(*this);
    newStr.size = newStr.size + str.size;
    if (newStr.size > newStr.capacity)
    {
        newStr.capacity = newStr.size + 1;
        delete[] newStr.string;
        newStr = new char[newStr.capacity];
        strcpy(newStr.string, this->string);
    }
    strcat(newStr.string, str.string);
#endif
    return newStr;
}

myString myString::operator-(const myString &str)
{
    myString newstr(*this);
    char *beginPos = strstr(newstr.string, str.string);
    while (beginPos != nullptr)
    {
        char *endPos = beginPos + strlen(str.string);
        while (*endPos != '\0')
        {
            *beginPos++ = *endPos++;
        }
        *beginPos = '\0';
        beginPos = strstr(newstr.string, str.string);
    }

    return newstr;
}

myString &myString::operator=(const myString &str)
{
    this->size = str.size;
    this->capacity = str.capacity;
    delete[] this->string;
    this->string = new char[str.capacity];
    strncpy(this->string, str.string, this->size);
    return *this;
}

myString &myString::operator+=(const myString &str)
{
    *this = *this + str;
    return *this;
}

myString &myString::operator-=(const myString &str)
{
    *this = *this - str;
    return *this;
}

bool myString::operator==(const myString &str)
{
    return strncmp(this->string, str.string, str.size) == 0;
}

bool myString::operator!=(const myString &str)
{
    return strncmp(this->string, str.string, str.size) != 0;
}

bool myString::operator&&(const myString &str)
{
    return this->size != 0 && str.size != 0;
}

char &myString::operator[](int idx)
{
    return this->string[idx];
}

myString::operator int()
{
    return std::stoi(this->string);
}

myString::operator double()
{
    return std::stof(this->string);
}

myString::~myString()
{
    delete[] this->string;
}

std::ostream &operator<<(std::ostream &os, const myString &str)
{
    os << str.string;
    return os;
}

std::istream &operator>>(std::istream &is, myString &str)
{
    is >> str.string;
    return is;
}
std::ostream &operator<<(std::ostream &os, const myStringList &list)
{
    for (int idx = 0; idx < list.size; idx++)
    {
        os << list.strList[idx] << std::endl;
    }
    return os;
}
myStringList::myStringList()
{
    this->size = 0;
    this->capacity = defaultSize;
    this->strList = new myString[capacity];
}
myStringList::~myStringList()
{
    delete[] this->strList;
}

myStringList &myStringList::operator+=(const myString &str)
{
    this->strList[this->size++] = str;
    return *this;
}

myStringList &myStringList::operator-=(const myString &str)
{
    for (int idx = 0; idx < this->size; idx++)
    {
        if (this->strList[idx] == str)
        {
            removeByIndex(idx);
            idx--;
        }
    }
    return *this;
}

void myStringList::removeByIndex(int idx)
{
    if (idx < 0 || idx >= this->size)
    {
        return;
    }
    for (int jdx = idx; jdx < this->size - 1; jdx++)
    {
        // delete this->strList[idx].string;
        this->strList[jdx] = this->strList[jdx + 1];
    }
    this->size--;
}
